﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Markup;

using alib;
using alib.Concurrency;
using alib.Dictionary;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[UsableDuringInitialization(true)]
	public class namescope_helper : INameScope
	{
		SlotDictionary<String, Object> _dict;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		SlotDictionary<String, Object> GetDict
		{
			get
			{
				SlotDictionary<String, Object> _tmp;
				return _dict ?? cmp.xchg(ref _dict, _tmp = new SlotDictionary<String, Object>(10), null) ?? _tmp;
			}
		}

		public bool _find_name(String name, out Object item)
		{
			if (name == null || name == "" || _dict == null)
			{
				item = null;
				return false;
			}
			return GetDict.TryGetValue(name, out item);
		}

		public Object FindName(String name)
		{
			if (name == null || name == "" || _dict == null)
				return null;

			Object obj;
			if (!GetDict.TryGetValue(name, out obj))
				return null;

			var mi = obj.GetType().GetMethod("get_Monad");
			if (mi != null)
				obj = (IIdentity)mi.Invoke(obj, null);

			return obj;
		}

		public void RegisterName(String name, Object item)
		{
			if (name == null || name == "" || item == null)
				return;

			if (!IsValidIdentifierName(name))
				throw new ArgumentException("Invalid XAML identifier string");

			Object _cur = item;
			if (!GetDict.TryAdd(name, ref _cur) && _cur != item)
				throw new DuplicateKeyException();
		}

		bool _unregister_name(String name)
		{
			if (name == null || name == "" || _dict == null)
				return false;

			return GetDict.Remove(name);
		}

		public void UnregisterName(String name) { _unregister_name(name); }

		[DebuggerStepThrough]
		public static bool IsValidIdentifierName(String name)
		{
			for (int i = 0; i < name.Length; i++)
			{
				UnicodeCategory k = char.GetUnicodeCategory(name[i]);
				bool flag = ((((k == UnicodeCategory.UppercaseLetter) || (k == UnicodeCategory.LowercaseLetter)) || ((k == UnicodeCategory.TitlecaseLetter) || (k == UnicodeCategory.OtherLetter))) || (k == UnicodeCategory.LetterNumber)) || (name[i] == '_');
				bool flag2 = (((k == UnicodeCategory.NonSpacingMark) || (k == UnicodeCategory.SpacingCombiningMark)) || (k == UnicodeCategory.ModifierLetter)) || (k == UnicodeCategory.DecimalDigitNumber);
				if (i == 0)
				{
					if (!flag)
						return false;
				}
				else if (!flag && !flag2)
					return false;
			}
			return true;
		}
	};
}
